package com.ciei.dpagm.service.conditionRule.factMode;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ciei.dpagm.common.enums.FactModeEnum;
import com.ciei.dpagm.entity.Parameter;
import com.ciei.dpagm.entity.ParameterModule;
import com.ciei.dpagm.service.ParameterModuleService;
import com.ciei.dpagm.service.ParameterService;
import com.ciei.dpagm.service.conditionRule.ConditionHandleService;
import com.ciei.dpagm.util.*;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据类型
 * @author pp
 * @date 2023/03/15
 */
public class DataTypeFactModeService extends AbstractFactModeService {

    private ParameterModuleService parameterModuleService;

    private ParameterService parameterService;


    @Override
    protected JSONObject analysis(List<String> factModeList, JSONObject originData,FactModeEnum twoFactModeEnum) {
        switch (twoFactModeEnum) {
            case KEY_VALUE_DATA_TYPE_SELECT_PARAMETER:
                parameterModuleService = ApplicationContextHolder.getBean(ParameterModuleService.class);
                parameterService = ApplicationContextHolder.getBean(ParameterService.class);
                if(factModeList.size() < 5){
                    return ConditionHandleService.ArraySizeNotMatchMessage(FactModeFactoryService.title);
                }
                String moduleValue = factModeList.get(moduleIdIndex);
                String parameterValue = factModeList.get(parameterValueIndex);
                ParameterModule parameterModule = parameterModuleService.findById(moduleValue);
                Parameter parameter = parameterService.findById(parameterValue);
                if(parameterModule == null){
                    return ConditionHandleService.notFoundParameterModuleDataMessage(FactModeFactoryService.title);
                }
                if(parameter == null){
                    return ConditionHandleService.notFoundParameterDataMessage(FactModeFactoryService.title);
                }
                if(parameter.getParameterName() == null){
                    return ConditionHandleService.parameterKeyIsNullMessage(FactModeFactoryService.title);
                }
                Parameter finalParameter = parameterService.findById(factModeList.get(factModeList.size() - 1));
                if(finalParameter == null){
                    return ConditionHandleService.notFoundParameterDataMessage(FactModeFactoryService.title);
                }
                if(finalParameter.getParameterName() == null){
                    return ConditionHandleService.parameterKeyIsNullMessage(FactModeFactoryService.title);
                }
                Integer valueIndex = parameterValueIndex;
                JSONObject parameterData = originData;
                while (factModeList.size() > valueIndex + 1) {
                    Parameter nextParameter = parameterService.findById(factModeList.get(valueIndex));
                    if(nextParameter == null){
                        return ConditionHandleService.notFoundParameterDataMessage(FactModeFactoryService.title);
                    }
                    if(nextParameter.getParameterName() == null){
                        return ConditionHandleService.parameterKeyIsNullMessage(FactModeFactoryService.title);
                    }
                    Object nextParameterValue = parameterData.get(nextParameter.getParameterName());
                    if(nextParameterValue == null){
                        return ConditionHandleService.originDataNotFoundParameterDataMessage(FactModeFactoryService.title);
                    }
                    if(nextParameterValue instanceof JSONObject){
                        parameterData = parameterData.getJSONObject(nextParameter.getParameterName());
                    } else if(nextParameterValue instanceof JSONArray){
                        List<String> resultList = new ArrayList<>();
                        JSONArray nextParameterList = parameterData.getJSONArray(nextParameter.getParameterName());
                        analyzeList(nextParameterList, resultList, valueIndex, factModeList);
                        return JsonUtil.getSuccess("").fluentPut(APP.DATA,resultList);
                    }else{
                        return ConditionHandleService.notSupportDataTypeMessage();
                    }
                    valueIndex++;
                }
                Object value = parameterData.get(finalParameter.getParameterName());
                String typeName = DataUtil.getTypeName(value);
                return JsonUtil.getSuccess("").fluentPut(APP.DATA,typeName);
            default:
                break;
        }
        return ConditionHandleService.notMatchAnalyzeMessage(FactModeFactoryService.twoFactModeIndex,FactModeFactoryService.title);
    }

    @Override
    protected void conversionOptionList(List<String> factModeList, List<JSONObject> sonFactModeOptionDataList,FactModeEnum twoFactModeEnum) {
        switch (twoFactModeEnum) {
            case KEY_VALUE_DATA_TYPE_SELECT_PARAMETER:
                conversionParameterOptionList(factModeList,sonFactModeOptionDataList,true);
                break;
            default:
                break;
        }
    }

    /**
     * 解析数组
     * @param parameterList
     * @param resultList
     * @param valueIndex
     * @param factModeList
     */
    public void analyzeList(JSONArray parameterList,List<String> resultList,Integer valueIndex,List<String> factModeList){
        // 数组的子对象设计问题，数据类型会默认生成子元素items，解析时需跳过items子节点
        Integer nextValueIndex = valueIndex + 2;
        if(parameterList.isEmpty()){
            return;
        }
        // 数组大小等于nextValueIndex，子元素为最后一级,
        if(factModeList.size() == nextValueIndex) {
            for (int i = 0; i < parameterList.size(); i++) {
                Object value = parameterList.get(i);
                String typeName = DataUtil.getTypeName(value);
                resultList.add(typeName);
            }
            return;
        }
        // 例:出现数组为10 nextValueIndex为9，表示，说明子元素为对象，需要获取子元素对象某个字段的值类型
        if(factModeList.size() == nextValueIndex + 1){
            Parameter nextParameter = parameterService.findById(factModeList.get(nextValueIndex));
            if(nextParameter == null){
                return;
            }
            if(nextParameter.getParameterName() == null){
                return;
            }
            for (int i = 0; i < parameterList.size(); i++) {
                Object value = parameterList.get(i);
                if(value instanceof JSONObject){
                    JSONObject valueData = parameterList.getJSONObject(i);
                    Object nextParameterValue = valueData.get(nextParameter.getParameterName());
                    if(nextParameterValue == null){
                        continue;
                    }
                    String typeName = DataUtil.getTypeName(nextParameterValue);
                    resultList.add(typeName);
                }
            }
            return;
        }
        for (int i = 0; i < parameterList.size(); i++) {
            Object parameterValue = parameterList.get(i);
            if(parameterValue instanceof JSONObject){
                Parameter nextParameter = parameterService.findById(factModeList.get(nextValueIndex));
                if(nextParameter == null){
                    continue;
                }
                if(nextParameter.getParameterName() == null){
                    continue;
                }
                JSONObject parameterData = parameterList.getJSONObject(i);
                Object nextParameterValue = parameterData.get(nextParameter.getParameterName());
                if (nextParameterValue instanceof JSONObject) {
                    JSONObject nextParameterData = parameterData.getJSONObject(nextParameter.getParameterName());
                    analyzeObject(nextParameterData, resultList, nextValueIndex, factModeList);
                }else if(nextParameterValue instanceof JSONArray){
                    JSONArray sonParameterList = parameterData.getJSONArray(nextParameter.getParameterName());
                     analyzeList(sonParameterList, resultList, nextValueIndex, factModeList);

                }
            }else if(parameterValue instanceof JSONArray){
                for (int j = 0; j < parameterList.size(); j++) {
                    JSONArray sonParameterList = parameterList.getJSONArray(j);
                    analyzeList(sonParameterList, resultList, nextValueIndex, factModeList);
                }
            }
        }
        return;
    }

    /**
     * 解析对象
     * @param parameterData
     * @param resultList
     * @param valueIndex
     * @param factModeList
     * @return
     */
    public void analyzeObject(JSONObject parameterData, List<String> resultList, Integer valueIndex, List<String> factModeList){
        Integer nextValueIndex = valueIndex + 1;
        if(factModeList.size() == nextValueIndex) {
            String typeName = DataUtil.getTypeName(parameterData);
            resultList.add(typeName);
        }
        Parameter nextParameter = parameterService.findById(factModeList.get(nextValueIndex));
        Object nextParameterValue = parameterData.get(nextParameter.getParameterName());
        if (nextParameterValue instanceof JSONObject) {
            JSONObject nextParameterData = parameterData.getJSONObject(nextParameter.getParameterName());
            analyzeObject(nextParameterData, resultList, nextValueIndex, factModeList);
        }else if(nextParameterValue instanceof JSONArray){
            JSONArray nextParameterList = parameterData.getJSONArray(nextParameter.getParameterName());
            analyzeList(nextParameterList, resultList, nextValueIndex, factModeList);
        }
    }
}
